#!/bin/bash
x=0
y=0
btn=0
action=""

enable_mouse_tracking() {
    echo -ne "\e[?1000h"
    echo -ne "\e[?1006h"
    echo -ne "\e[?1015h"
}

disable_mouse_tracking() {
    echo -ne "\e[?1015l"
    echo -ne "\e[?1006l"
    echo -ne "\e[?1000l"
}
case_btn() {
case $btn in 
    0) action="左键" ;;
    1) action="中键" ;;
    2) action="右键" ;;
    3) action="释放" ;;
    32) action="移动" ;;
    64) action="滚轮上" ;;
    65) action="滚轮下" ;;
    *) action="按钮${btn}" ;;
esac
}

mouse_output() {
    printf "事件: %-8s 坐标: X=%-3d Y=%-3d\n" "$action" "$x" "$y"
}
parse_mouse_event() {
    local input=$1
    
    if [[ "$input" =~ ^([0-9]+)\;([0-9]+)\;([0-9]+)[mM]$ ]]; then
        btn=${BASH_REMATCH[1]}
        x=${BASH_REMATCH[2]}
        y=${BASH_REMATCH[3]}
        case_btn
        if ((btn & 0x20)); then
            [[ "$action" != "释放" ]] && action="${action}释放"
        fi
        mouse_output
        return 0
    elif [[ "$input" =~ ^([0-9]+)\;([0-9]+)\;([0-9]+)M$ ]]; then
        btn=${BASH_REMATCH[1]}
        x=${BASH_REMATCH[2]}
        y=${BASH_REMATCH[3]}
        case_btn
        mouse_output
        return 0
    elif [[ "${#input}" -eq 3 && "${input:0:1}" == $'\e' ]]; then
        btn=$(printf "%d" "'${input:1:1}")
        x=$(( $(printf "%d" "'${input:2:1}") - 32 ))
        y=$(( $(printf "%d" "'${input:3:1}") - 32 ))
        case_btn
        mouse_output
        return 0
    
    else
        if [[ "$input" =~ ^([0-9]+)\;([0-9]+)\;([0-9]+) ]]; then
            btn=${BASH_REMATCH[1]}
            x=${BASH_REMATCH[2]}
            y=${BASH_REMATCH[3]}
            case_btn
            mouse_output
            return 0
        else
            echo "未知输入: $input"
            return 1
        fi
    fi
}
main() {
    trap 'disable_mouse_tracking; stty sane; echo; exit' EXIT INT
    enable_mouse_tracking
    stty -echo -icanon time 0 min 0
    echo "开始监听鼠标事件 (按Ctrl+C退出)..."
    while true; do
        read -rsn1 char
        [[ -z "$char" ]] && continue
        if [[ "$char" == $'\e' ]]; then
            read -rsn2 -t 0.01 prefix
            if [[ "$prefix" == '[<' ]]; then
                IFS=';' read -rs -d '[Mm]' btn x y
                parse_mouse_event "$btn;$x;$y${prefix:1:1}"
            elif [[ "$prefix" == '[M' ]]; then
                read -rsn3 code
                parse_mouse_event "$code"
            elif [[ "$prefix" =~ ^[0-9] ]]; then
                IFS=';' read -rs -d 'M' btn x y <<< "${prefix}$(cat)"
                parse_mouse_event "$btn;$x;$y"M
            else
                read -rsn5 -t 0.01 extra
                parse_mouse_event "${prefix}${extra}"
            fi
        fi
    done
}
main